home *** CD-ROM | disk | FTP | other *** search
- PAGE 66,132
- VECTORS SEGMENT AT 0H
- ORG 8H*4
- TOD_VECTOR LABEL DWORD ; CLOCK INTERRUPT
- ORG 13H*4
- DISK_VECTOR LABEL DWORD ; HARD DISK BIOS CALL
- VECTORS ENDS
- ;
- ; THIS IS THE START OF THE LOCAL DATA AND EXECUTABLE CODE
- ;
- CODE_SEG SEGMENT
- ASSUME CS:CODE_SEG
- ORG 100H
- BEGIN: CALL PARK ; FIND OUT WHERE TO PARK
- JMP INIT_VECTORS ;INITIALIZE VECTORS & ATTACH TO DOS
- ROM_TOD_INT DD ? ; ADDRESSES FOR ROM ROUTINES
- ROM_DISK_INT DD ?
- TIMER_DELAY DW 546 ; DELAY BEFORE PARKING HEAD
- DELAY DW ? ; CLOCK TICKS DURING DELAY
- BUSY DB 0
- CYLNUM0 DW 0
- CYLNUM1 DW 0
- ;
- ; PARK THE HARD DISK HEAD AFTER DELAY WITHOUT USE
- ;
- ;
- OUR_TOD_INT PROC NEAR
- PUSHF
- CALL ROM_TOD_INT ; GO TO OTHER CODE FIRST
- PUSH AX
- PUSH DS
- MOV AX,CS ; SET DATA SEGMENT TO OURSELF
- MOV DS,AX
- ASSUME DS:CODE_SEG
- DEC DELAY ; HAS DELAY ELAPSED?
- JZ PARK_IT ; YUP
- JG COUNT_DOWN ; NOPE
- MOV DELAY,0 ; HEAD IS PARKED, RESET COUNTER TO 0
- COUNT_DOWN: POP DS
- POP AX
- ASSUME DS:NOTHING
- IRET
- PARK_IT: ASSUME DS:CODE_SEG
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- TEST BUSY,80H ; IS DISK CODE BUSY?
- JNZ IT_IS_BUSY ; OOPS, YES
- CMP CYLNUM0,0 ; IS THERE A DISK 0?
- JE NODISK0 ; NOPE
- MOV AH,0CH ; SEEK
- MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
- MOV DL,80H ; DRIVE 0
- MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
- MOV CX,CYLNUM0 ; GET CYL NUMBER
- XCHG CL,CH ; PUT LO ORDER IN CH
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- INC CL ; NOW SAY SECTOR 1
- PUSHF
- CALL ROM_DISK_INT ; MUST USE CALL SINCE INT 13H > HERE
- NODISK0:
- CMP CYLNUM1,0 ; IS THERE A DISK 1?
- JE NODISK1 ; NO
- MOV AH,0CH ; SEEK
- MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
- MOV DL,81H ; DRIVE 1
- MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
- MOV CX,CYLNUM1 ; GET CYL NUMBER
- XCHG CL,CH ; PUT LO ORDER IN CH
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- INC CL ; NOW SAY SECTOR 1
- PUSHF
- CALL ROM_DISK_INT ; MUST USE CALL SINCE INT 13H > HERE
- NODISK1:
- POP DX
- POP CX
- POP BX
- POP AX
- JMP COUNT_DOWN
- IT_IS_BUSY: CALL RESET ; DISK IS BUSY, WAIT ANOTHER 5 SEC
- POP DX
- POP CX
- POP BX
- POP AX
- JMP COUNT_DOWN
- OUR_TOD_INT ENDP
- ;
- ; THIS PROCEDURE RESETS THE TIMER COUNT TO ITS INITIAL VALUE
- ;
- RESET PROC NEAR
- PUSH AX
- PUSH DS
- MOV AX,CS
- MOV DS,AX
- ASSUME DS:CODE_SEG
- MOV AX,TIMER_DELAY
- MOV DELAY,AX
- POP DS
- POP AX
- RET
- RESET ENDP
- ;
- ;
- ; THIS PROCEDURE RESETS THE TIME-OUT COUNTER AND PASSES CONTROL
- ; TO THE BIOS DISK ROUTINES
- ;
- CATCH_DISK PROC FAR
- ASSUME DS:NOTHING
- OR BUSY,80H ; MARK DISK BUSY
- TEST DL,80H ; IS IT A HARD DISK CALL?
- JZ NORESET ; NO
- CALL RESET ; RESET THE TIME-OUT COUNTER
- NORESET: PUSHF ; SIMULATE INTERRUPT
- CALL ROM_DISK_INT ; DO BIOS STUFF
- PUSHF ; REMEMBER FLAGS FROM DISK ROUTINE
- AND BUSY,7FH ; MARK DISK NOT BUSY
- POPF ; REMEMBER FLAGS FROM DISK ROUTINE
- RET 2 ; THROW AWAY USER'S SAVED FLAGS
- CATCH_DISK ENDP
- ;
- ; THIS PROCEDURE INITIALIZES THE INTERRUPT VECTORS
- ;
- INIT_VECTORS PROC NEAR
- ASSUME DS:VECTORS
- MOV AX,VECTORS ; SET UP DATA SEGMENT FOR VECTORS
- MOV DS,AX
- CLI
- MOV AX,WORD PTR TOD_VECTOR ; SAVE ADDRESSES OF BIOS ROUTINES
- MOV WORD PTR ROM_TOD_INT,AX
- MOV AX,WORD PTR TOD_VECTOR[2]
- MOV WORD PTR ROM_TOD_INT[2],AX
- MOV WORD PTR TOD_VECTOR,OFFSET OUR_TOD_INT
- MOV WORD PTR TOD_VECTOR[2],CS
- MOV AX,WORD PTR DISK_VECTOR
- MOV WORD PTR ROM_DISK_INT,AX
- MOV AX,WORD PTR DISK_VECTOR[2]
- MOV WORD PTR ROM_DISK_INT[2],AX
- MOV WORD PTR DISK_VECTOR,OFFSET CATCH_DISK
- MOV WORD PTR DISK_VECTOR[2],CS
- MOV AX,TIMER_DELAY ; SET DELAY TO STARTING COUNT
- MOV DELAY,AX
- STI ; ALLOW INTERRUPTS AGAIN
- MOV DX,OFFSET INIT_VECTORS ; END OF RESIDENT PORTION
- INT 27H ; TERMINATE BUT STAY RESIDENT
- INIT_VECTORS ENDP
- SUBTTL PARK -- PARK THE HEADS IN ORDER TO FIND OUT WHERE TO PARK
- PAGE
- PARK PROC
- PUSH AX
- PUSH CX
- PUSH DX
- PUSH ES
- ;
- ; MOVE DRIVE 0 AS FAR AS POSSIBLE IN STEPS OF 100 TRACKS
- ;
- SEEK0100: MOV AH,0CH ; SEEK
- MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
- MOV DL,80H ; DRIVE 0
- MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
- MOV CX,CYLNUM0 ; GET CYLINDER NUMBER
- ADD CX,100 ; INCREMENT BY 100
- MOV CYLNUM0,CX ; PUT IT BACK
- XCHG CL,CH ; PUT LO ORDER IN CH
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- INC CL ; NOW SAY SECTOR 1
- INT 13H
- MOV AH,01H ; CHECK STATUS
- MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
- MOV DL,80H ; DRIVE 0
- MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
- MOV CX,1 ; CYL 0 SECTOR 1
- INT 13H
- OR AL,AL
- JZ SEEK0100
- MOV AX,CYLNUM0
- SUB AX,100
- MOV CYLNUM0,AX
- ;
- ; MOVE DRIVE 0 AS FAR AS POSSIBLE IN STEPS OF 10 TRACKS
- ;
- SEEK010: MOV AH,0CH ; SEEK
- MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
- MOV DL,80H ; DRIVE 0
- MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
- MOV CX,CYLNUM0 ; GET CYLINDER NUMBER
- ADD CX,10 ; INCREMENT BY 10
- MOV CYLNUM0,CX ; PUT IT BACK
- XCHG CL,CH ; PUT LO ORDER IN CH
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- INC CL ; NOW SAY SECTOR 1
- INT 13H
- MOV AH,01H ; CHECK STATUS
- MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
- MOV DL,80H ; DRIVE 0
- MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
- MOV CX,1 ; CYL 0 SECTOR 1
- INT 13H
- OR AL,AL
- JZ SEEK010
- MOV AX,CYLNUM0
- SUB AX,10
- MOV CYLNUM0,AX
- ;
- ; MOVE DRIVE 0 AS FAR AS POSSIBLE IN STEPS OF 1 TRACK
- ;
- SEEK01: MOV AH,0CH ; SEEK
- MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
- MOV DL,80H ; DRIVE 0
- MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
- INC CYLNUM0 ; INCREMENT CYLINDER NUM
- MOV CX,CYLNUM0 ; GET CYL NUMBER
- XCHG CL,CH ; PUT LO ORDER IN CH
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- INC CL ; NOW SAY SECTOR 1
- INT 13H
- MOV AH,01H ; CHECK STATUS
- MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
- MOV DL,80H ; DRIVE 0
- MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
- MOV CX,1 ; CYL 0 SECTOR 1
- INT 13H
- OR AL,AL
- JZ SEEK01
- DEC CYLNUM0
- CMP CYLNUM0,0
- JE NODRIVE0
- MOV AX,CYLNUM0
- PUSH DS
- POP ES
- LEA DX,CYLDEC0
- CALL DECIMAL_CONVERT
- MOV AH,9
- LEA DX,CYLMSG0
- INT 21H
- NODRIVE0:
- ;
- ; MOVE DRIVE 1 AS FAR AS POSSIBLE IN STEPS OF 100 TRACKS
- ;
- SEEK1100: MOV AH,0CH ; SEEK
- MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
- MOV DL,81H ; DRIVE 1
- MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
- MOV CX,CYLNUM1 ; GET CYLINDER NUMBER
- ADD CX,100 ; INCREMENT BY 100
- MOV CYLNUM1,CX ; PUT IT BACK
- XCHG CL,CH ; PUT LO ORDER IN CH
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- INC CL ; NOW SAY SECTOR 1
- INT 13H
- MOV AH,01H ; CHECK STATUS
- MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
- MOV DL,81H ; DRIVE 1
- MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
- MOV CX,1 ; CYL 0 SECTOR 1
- INT 13H
- OR AL,AL
- JZ SEEK1100
- MOV AX,CYLNUM1
- SUB AX,100
- MOV CYLNUM1,AX
- ;
- ; MOVE DRIVE 1 AS FAR AS POSSIBLE IN STEPS OF 10 TRACKS
- ;
- SEEK110: MOV AH,0CH ; SEEK
- MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
- MOV DL,81H ; DRIVE 1
- MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
- MOV CX,CYLNUM1 ; GET CYLINDER NUMBER
- ADD CX,10 ; INCREMENT BY 10
- MOV CYLNUM1,CX ; PUT IT BACK
- XCHG CL,CH ; PUT LO ORDER IN CH
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- INC CL ; NOW SAY SECTOR 1
- INT 13H
- MOV AH,01H ; CHECK STATUS
- MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
- MOV DL,81H ; DRIVE 1
- MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
- MOV CX,1 ; CYL 0 SECTOR 1
- INT 13H
- OR AL,AL
- JZ SEEK110
- MOV AX,CYLNUM1
- SUB AX,10
- MOV CYLNUM1,AX
- ;
- ; MOVE DRIVE 0 AS FAR AS POSSIBLE IN STEPS OF 1 TRACK
- ;
- SEEK1: MOV AH,0CH ; SEEK
- MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
- MOV DL,81H ; DRIVE 1
- MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
- INC CYLNUM1 ; INCREMENT CYLINDER NUM
- MOV CX,CYLNUM1 ; GET CYL NUMBER
- XCHG CL,CH ; PUT LO ORDER IN CH
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- SAL CL,1 ; PUT HI IN TOP OF CL
- INC CL ; NOW SAY SECTOR 1
- INT 13H
- MOV AH,01H ; CHECK STATUS
- MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
- MOV DL,81H ; DRIVE 1
- MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
- MOV CX,1 ; CYL 0 SECTOR 1
- INT 13H
- OR AL,AL
- JZ SEEK1
- DEC CYLNUM1
- CMP CYLNUM1,0
- JE NODRIVE1
- MOV AX,CYLNUM1
- PUSH DS
- POP ES
- LEA DX,CYLDEC1
- CALL DECIMAL_CONVERT
- MOV AH,9
- LEA DX,CYLMSG1
- INT 21H
- NODRIVE1:
- MOV AH,9
- LEA DX,BLANKLINE
- INT 21H
- POP ES
- POP DX
- POP CX
- POP AX
- RET
- CYLMSG0 DB 0AH,0DH,"Hard disk 0 parking place is cylinder"
- CYLDEC0 DB " .$"
- CYLMSG1 DB 0AH,0DH,"Hard disk 1 parking place is cylinder"
- CYLDEC1 DB " .$"
- BLANKLINE DB 0AH,0DH,"$"
- PARK ENDP
- SUBTTL DECIMAL CONVERT (TO ASCII STRING FOR DISPLAY)
- PAGE
- ;
- ; DECIMAL_CONVERT IS ENTERED WITH A NUMBER IN AX AND ES:DX POINTING TO
- ; A FIVE-BYTE FIELD. IT CONVERTS THE NUMBER INTO A FIVE-BYTE INTEGER
- ; FROM 0 TO 65535 AND PLACES IT IN ASCII IN THE FIVE-BYTE FIELD.
- ; IT ALTERS NO REGISTERS AT ALL.
- ;
- DECIMAL_CONVERT PROC
- PUSH BX
- PUSH DX
- PUSH DI
- ASSUME ES:NOTHING
- ;
- ; DIVIDE BY TEN TO GET UNITS AS REMAINDER
- ;
- MOV DI,DX
- MOV BX,10 ; DIVISOR
- MOV DX,0 ; HIGH ORDER MUST BE ZERO
- DIV BX ; DIVIDE -- REMAINDER IN DX
- ADD DL,"0" ; MAKE REMAINDER ASCII
- MOV BYTE PTR ES:[DI+4],DL ; PUT BYTE IN DESTINATION
- ;
- ; DIVIDE AGAIN FOR TENS
- ;
- MOV DX,0 ; HIGH ORDER MUST BE ZERO
- DIV BX
- ADD DL,"0"
- MOV BYTE PTR ES:[DI+3],DL
- ;
- ; DIVIDE AGAIN FOR HUNDREDS
- ;
- MOV DX,0
- DIV BX
- ADD DL,"0"
- MOV BYTE PTR ES:[DI+2],DL
- ;
- ; THOUSANDS
- ;
- MOV DX,0
- DIV BX
- ADD DL,"0"
- MOV BYTE PTR ES:[DI+1],DL
- ;
- ; TEN-THOUSANDS
- ;
- MOV DX,0
- DIV BX
- ADD DL,"0"
- MOV BYTE PTR ES:[DI],DL
- ;
- ; GET RID OF LEADING ZEROS
- ;
- CMP BYTE PTR ES:[DI],"0"
- JNE DECIMAL_DONE
- MOV BYTE PTR ES:[DI]," "
- CMP BYTE PTR ES:[DI+1],"0"
- JNE DECIMAL_DONE
- MOV BYTE PTR ES:[DI+1]," "
- CMP BYTE PTR ES:[DI+2],"0"
- JNE DECIMAL_DONE
- MOV BYTE PTR ES:[DI+2]," "
- CMP BYTE PTR ES:[DI+3],"0"
- JNE DECIMAL_DONE
- MOV BYTE PTR ES:[DI+3]," "
- DECIMAL_DONE:
- POP DI
- POP DX
- POP BX
- RET
- DECIMAL_CONVERT ENDP
- CODE_SEG ENDS
- END BEGIN